import React, { useEffect, useRef, forwardRef, useImperativeHandle, useCallback } from 'react';

// UEditor 组件的属性接口定义
interface UEditorProps {
    value?: string; // 编辑器的内容值
    onChange?: (content: string) => void; // 内容变化时的回调函数
    style?: React.CSSProperties; // 容器的样式
    config?: Record<string, any>; // UEditor 的配置对象
    imgResizable?: boolean; // 图片是否可调整大小
    imgFixedWidth?: number | string; // 图片固定宽度
    multiImageMaxCount?: number; // 多图上传最大数量
    multiImageMaxSize?: number; // 多图上传最大文件大小（KB）
    multiImageAllowFiles?: string[]; // 多图上传允许的文件类型
    multiImageUploadUrl?: string; // 多图上传接口地址
    multiImageFieldName?: string; // 多图上传字段名
    onBlur?: () => void; // 编辑器失去焦点时的回调
    placeholder?: string; // 添加 placeholder 属性
    onMultiImageUploadSuccess?: (images: any[]) => void; // 多图上传成功回调
    onMultiImageUploadError?: (error: { // 多图上传失败回调
        message: string;
        data?: any;
        status?: number;
        response?: string;
        error?: any;
    }) => void;
}

// 全局变量声明
declare global {
    interface Window {
        UE: any; // UEditor 全局对象
        loader?: { // 加载器对象
            load: (
                urls: string[],
                callback: () => void,
                errorCallback: (err: any) => void
            ) => void;
        };
    }
}

// 默认配置项
const DEFAULT_CONFIG = {
    imgResizable: false,   // 是否允许图片调整大小
    imgFixedWidth: 100,    // 图片固定宽度，可以是百分比或像素值
    multiImageMaxCount: 6,    // 多图上传最大数量
    multiImageMaxSize: 5 * 1024,    // 多图上传最大文件大小（KB）
    multiImageAllowFiles: ['.png', '.jpg', '.jpeg', '.gif', '.bmp'],    // 多图上传允许的文件类型
    multiImageUploadUrl: '/pc/common/ueditor',    // 多图上传接口地址
    multiImageFieldName: 'upfile',      // 多图上传字段名
};

// 暴露给父组件的方法接口
export interface UEditorRef {
    getContent: () => string; // 获取编辑器内容
    setContent: (content: string) => void; // 设置编辑器内容
    getPlainText: () => string; // 获取纯文本内容
    forceImageFixedSize: () => void; // 强制修正图片尺寸
    ueditorInstance: any; // UEditor 实例
}

// UEditor 组件主体
const UEditor = forwardRef<UEditorRef, UEditorProps>((props, ref) => {
    // 使用 ref 来引用编辑器容器
    const editorContainer = useRef<HTMLDivElement>(null);
    // 存储 UEditor 实例
    const ueInstance = useRef<any>(null);
    // 标记是否正在初始化编辑器
    const isInitializing = useRef(false);
    // 标记是否正在修正图片尺寸
    const isFixingImages = useRef(false);
    // 标记是否正在更新内容（避免循环更新）
    const isContentUpdating = useRef(false);
    // 内容变化定时器引用
    const contentChangeTimerRef = useRef<NodeJS.Timeout | null>(null);
    // 标记当前是否是占位符状态
    const isPlaceholderActive = useRef(false);

    // 从 props 中解构属性，并提供默认值
    const {
        value = '', // 编辑器内容，默认为空字符串
        onChange, // 内容变化回调函数
        style, // 容器样式
        config = {}, // UEditor 配置，默认为空对象
        imgResizable = DEFAULT_CONFIG.imgResizable, // 图片是否可调整大小，默认为 false
        imgFixedWidth = DEFAULT_CONFIG.imgFixedWidth, // 图片固定宽度，默认为 100%
        multiImageMaxCount = DEFAULT_CONFIG.multiImageMaxCount, // 多图上传最大数量，默认为 9
        multiImageMaxSize = DEFAULT_CONFIG.multiImageMaxSize, // 多图上传最大文件大小，默认为 5MB
        multiImageAllowFiles = DEFAULT_CONFIG.multiImageAllowFiles, // 允许的文件类型
        multiImageUploadUrl = DEFAULT_CONFIG.multiImageUploadUrl, // 上传接口地址
        multiImageFieldName = DEFAULT_CONFIG.multiImageFieldName, // 上传字段名
        onBlur, // 失去焦点回调
        placeholder = '请输入内容文字...', // 默认提示文本
        onMultiImageUploadSuccess, // 多图上传成功回调
        onMultiImageUploadError, // 多图上传失败回调
    } = props;

    // UEditor 资源文件的基础路径
    const UEDITOR_BASE_PATH = '/UEditor';

    /**
     * 获取固定宽度的格式化值
     * 如果是数字，转换为百分比字符串；如果是字符串，直接返回
     */
    const getFixedWidth = useCallback(() => {
        if (typeof imgFixedWidth === 'number') {
            return `${imgFixedWidth}%`; // 数字转换为百分比
        }
        return imgFixedWidth as string; // 字符串直接返回
    }, [imgFixedWidth]);

    /**
     * 更新 CSS 变量，用于控制图片宽度
     */
    const updateCssVariable = useCallback(() => {
        document.documentElement.style.setProperty('--img-fixed-width', getFixedWidth());
    }, [getFixedWidth]);

    /**
     * 检查内容是否为空（排除占位符）
     */
    const isEmptyContent = useCallback((content: string) => {
        return !content ||
            content === '<p><br></p>' ||
            content === '' ||
            content === `<p style="color: #999; font-style: italic;">${placeholder}</p>` ||
            content.includes('请输入内容文字');
    }, [placeholder]);

    /**
     * 设置占位符文本
     */
    const setPlaceholderText = useCallback(() => {
        if (!ueInstance.current) return;

        const placeholderHtml = `<p style="color: #999; font-style: italic;">${placeholder}</p>`;
        ueInstance.current.setContent(placeholderHtml);
        isPlaceholderActive.current = true;

        // 占位符状态下不触发 onChange
        onChange?.('');
    }, [placeholder, onChange]);

    /**
     * 清除占位符文本
     */
    const clearPlaceholderText = useCallback(() => {
        if (!ueInstance.current) return;

        ueInstance.current.setContent('');
        isPlaceholderActive.current = false;
    }, []);

    /**
     * 安全地修正图片尺寸
     * @param force - 是否强制修正，即使正在修正中也要执行
     */
    const safeImageSizeFix = useCallback((force = false) => {
        // 如果编辑器实例不存在，或者非强制修正且正在修正中，则直接返回
        if (!ueInstance.current || (!force && isFixingImages.current)) return;

        // 标记开始修正图片尺寸
        isFixingImages.current = true;

        try {
            const editor = ueInstance.current;
            if (!editor) return;

            let doc: Document;
            try {
                // 尝试获取编辑器文档对象
                doc = editor.document || document;
                const iframe = doc.querySelector('iframe');
                if (iframe && iframe.contentDocument) {
                    doc = iframe.contentDocument; // 使用 iframe 内的文档
                }
            } catch (error) {
                console.warn('无法访问编辑器文档:', error);
                return;
            }

            if (!doc || !doc.body) return;

            // 获取所有图片元素
            const imgElements = doc.body.querySelectorAll('img');

            // 遍历所有图片进行处理
            imgElements.forEach((img: HTMLImageElement) => {
                try {
                    // 移除内联样式中的宽高设置
                    if (img.style.width) img.style.width = '';
                    if (img.style.height) img.style.height = '';

                    // 设置响应式样式 - 这是调整宽高的关键部分
                    img.style.maxWidth = '100%'; // 最大宽度为容器宽度
                    img.style.height = 'auto'; // 高度自适应，保持比例

                    // 移除 HTML 属性中的宽高设置
                    img.removeAttribute('width');
                    img.removeAttribute('height');

                    // 移除 alt 和 title 属性
                    img.removeAttribute('alt');
                    img.removeAttribute('title');

                    // 标记图片类型（单图或多图）
                    if (!img.hasAttribute('data-multi') && !img.hasAttribute('data-single')) {
                        img.setAttribute('data-single', 'true');
                    }
                } catch (imgError) {
                    console.warn('处理图片时出错:', imgError);
                }
            });

        } catch (error) {
            console.warn('修正图片尺寸时发生错误:', error);
        } finally {
            // 无论成功与否，最终都要重置修正状态
            setTimeout(() => {
                isFixingImages.current = false;
            }, force ? 200 : 0);
        }
    }, []);

    // 使用 useImperativeHandle 暴露方法给父组件
    useImperativeHandle(ref, () => ({
        /**
         * 获取编辑器内容（HTML），排除占位符
         */
        getContent: () => {
            const content = ueInstance.current?.getContent() || '';
            return isPlaceholderActive.current ? '' : content;
        },

        /**
         * 设置编辑器内容
         * @param content - 要设置的内容
         */
        setContent: (content: string) => {
            if (ueInstance.current && ueInstance.current.isReady) {
                isContentUpdating.current = true; // 标记正在更新内容

                if (isEmptyContent(content)) {
                    setPlaceholderText(); // 设置占位符
                } else {
                    ueInstance.current.setContent(content);
                    isPlaceholderActive.current = false;
                }

                setTimeout(() => {
                    safeImageSizeFix(true); // 强制修正图片尺寸
                    isContentUpdating.current = false; // 重置更新状态
                }, 50);
            }
        },

        /**
         * 获取纯文本内容，排除占位符
         */
        getPlainText: () => {
            const plainText = ueInstance.current?.getPlainTxt() || '';
            return isPlaceholderActive.current ? '' : plainText;
        },

        /**
         * 强制修正图片尺寸
         */
        forceImageFixedSize: () => safeImageSizeFix(true),

        /**
         * 获取 UEditor 实例
         */
        ueditorInstance: ueInstance.current,

        /**
         * 检查当前是否是占位符状态
         */
        isPlaceholderActive: () => isPlaceholderActive.current,
    }));

    /**
     * 动态加载脚本文件
     * @param src - 脚本文件路径
     * @returns Promise 对象
     */
    const loadScript = useCallback((src: string) => {
        return new Promise((resolve, reject) => {
            // 检查脚本是否已加载
            if (document.querySelector(`script[src="${src}"]`)) {
                return resolve(true);
            }

            // 创建 script 元素
            const script = document.createElement('script');
            script.src = src;
            script.onload = () => resolve(true);
            script.onerror = () => reject(new Error(`加载失败: ${src}`));
            document.body.appendChild(script);
        });
    }, []);

    /**
     * 初始化资源加载器
     */
    const initLoader = useCallback(() => {
        if (!window.loader) {
            window.loader = {
                load: (urls: string[], callback: () => void, errorCallback: (err: any) => void) => {
                    // 过滤掉已加载的 URL
                    const filteredUrls = urls.filter(url =>
                        !document.querySelector(`script[src="${url}"]`)
                    );

                    // 如果没有需要加载的 URL，直接执行回调
                    if (filteredUrls.length === 0) {
                        callback();
                        return;
                    }

                    // 加载单个脚本的函数
                    const loadScript = (url: string) => {
                        return new Promise((resolve, reject) => {
                            const script = document.createElement('script');
                            script.src = url;
                            script.onload = resolve;
                            script.onerror = (err) => {
                                console.warn(`资源加载失败: ${url}`, err);
                                reject(err);
                            };
                            document.head.appendChild(script);
                        });
                    };

                    // 并行加载所有脚本
                    Promise.all(filteredUrls.map(loadScript))
                        .then(callback)
                        .catch(errorCallback);
                }
            };
        }
    }, []);

    /**
     * 安全销毁编辑器实例
     */
    const safeDestroyEditor = useCallback(() => {
        // 清除内容变化定时器
        if (contentChangeTimerRef.current) {
            clearTimeout(contentChangeTimerRef.current);
            contentChangeTimerRef.current = null;
        }

        if (!ueInstance.current) return;

        try {
            // 需要移除的事件监听器列表
            const listeners = [
                'contentChange', 'blur', 'focus', 'afterUpload', 'afterInsertImage',
                'uploadSuccess', 'uploadError', 'error', 'keydown',
                'keyup', 'mouseup'
            ];

            // 移除所有事件监听器
            listeners.forEach(event => {
                try {
                    ueInstance.current.removeAllListeners?.(event);
                } catch (error) {
                    console.warn(`移除监听器 ${event} 失败:`, error);
                }
            });

            // 从 UEditor 实例管理中移除
            if (window.UE?.instances?.[ueInstance.current.key]) {
                window.UE.delEditor(ueInstance.current.key);
            }

            ueInstance.current = null;
        } catch (error) {
            console.warn('UEditor 销毁警告:', error);
        }
    }, []);

    /**
     * 设置图片处理器 - 监听图片相关事件
     */
    const setupImageHandlers = useCallback(() => {
        if (!ueInstance.current) {
            console.warn('UEditor实例不存在');
            return;
        }

        // 图片插入事件处理函数
        const handleImageInsert = () => {
            setTimeout(() => {
                safeImageSizeFix(true); // 插入图片后修正尺寸
            }, 100);
        };

        // 监听图片插入相关事件
        ueInstance.current.addListener('afterInsertImage', handleImageInsert); // 图片插入后
        ueInstance.current.addListener('afterUpload', handleImageInsert); // 上传完成后
        ueInstance.current.addListener('contentChange', () => {
            // 内容变化时延迟处理图片
            setTimeout(() => {
                safeImageSizeFix(false);
            }, 50);
        });

        // 覆盖 insertImage 方法以修正图片尺寸
        if (ueInstance.current.insertImage && typeof ueInstance.current.insertImage === 'function') {
            const originalInsertImage = ueInstance.current.insertImage;
            ueInstance.current.insertImage = function (url: string | string[], alt = '', href = '') {
                const result = originalInsertImage.call(this, url, alt, href);
                setTimeout(() => {
                    safeImageSizeFix(true); // 插入后修正尺寸
                }, 50);
                return result;
            };
        }
    }, [safeImageSizeFix]);

    /**
     * 设置占位符相关的事件处理
     */
    const setupPlaceholderHandlers = useCallback(() => {
        if (!ueInstance.current) return;
        // 焦点事件 - 清除占位符
        ueInstance.current.addListener('focus', () => {
            if (isPlaceholderActive.current) {
                clearPlaceholderText();
            }
        });
        // 失去焦点事件 - 显示占位符（如果内容为空）
        ueInstance.current.addListener('blur', () => {
            const content = ueInstance.current.getContent();
            if (isEmptyContent(content)) {
                setPlaceholderText();
            }
            onBlur?.();
        });
        // 内容变化事件 - 处理占位符逻辑
        ueInstance.current.addListener('contentChange', () => {
            if (!ueInstance.current?.isReady || isContentUpdating.current) return;
            // 防抖处理，避免频繁触发 onChange
            if (contentChangeTimerRef.current) {
                clearTimeout(contentChangeTimerRef.current);
            }
            contentChangeTimerRef.current = setTimeout(() => {
                const content = ueInstance.current.getContent();
                // 检查是否是占位符文本
                if (content.includes(placeholder) || isEmptyContent(content)) {
                    if (!isPlaceholderActive.current) {
                        isPlaceholderActive.current = true;
                        onChange?.(''); // 传递空内容
                    }
                } else {
                    isPlaceholderActive.current = false;
                    onChange?.(content); // 传递实际内容
                }
            }, 200);
        });

    }, [placeholder, isEmptyContent, setPlaceholderText, clearPlaceholderText, onChange, onBlur]);

    /**
     * 初始化 UEditor 编辑器
     */
    const initEditor = useCallback(async () => {
        // 如果正在初始化或容器不存在，直接返回
        if (isInitializing.current || !editorContainer.current) return;
        isInitializing.current = true; // 标记开始初始化

        try {
            initLoader(); // 初始化资源加载器
            // 加载 UEditor 资源文件
            if (!window.UE) {
                await loadScript(`${UEDITOR_BASE_PATH}/ueditor.config.js`); // 配置文件
                await loadScript(`${UEDITOR_BASE_PATH}/ueditor.all.min.js`); // 主文件
                await loadScript(`${UEDITOR_BASE_PATH}/lang/zh-cn/zh-cn.js`); // 语言文件
            }
            // 检查 UEditor 是否加载成功且容器存在
            if (window.UE && editorContainer.current && document.contains(editorContainer.current)) {
                safeDestroyEditor(); // 安全销毁现有实例

                // 为容器设置唯一 ID（如果没有的话）
                if (!editorContainer.current.id) {
                    editorContainer.current.id = `ueditor-${Date.now()}`;
                }

                // 编辑器配置对象 - 这是调整编辑器宽高的关键配置
                const editorConfig = {
                    UEDITOR_HOME_URL: UEDITOR_BASE_PATH + '/', // UEditor 主目录
                    serverUrl: multiImageUploadUrl, // 服务器地址
                    // 禁用 URL 处理
                    imageUrlPrefix: '',
                    imagePathFormat: '',
                    zIndex: 9,  // 编辑器整体层级
                    // 图片上传配置
                    imageActionName: 'uploadimage', // 图片上传动作名
                    imageFieldName: multiImageFieldName, // 图片字段名
                    imageMaxSize: multiImageMaxSize * 1024, // 图片最大大小（转换为字节）
                    imageAllowFiles: multiImageAllowFiles, // 允许的图片类型
                    imageMultiUpload: true, // 启用多图上传

                    // 编辑器基础配置 - 调整宽高的关键配置
                    initialFrameWidth: '90%', // 编辑器初始宽度 - 可调整宽度
                    initialFrameHeight: 240, // 编辑器初始高度 - 可调整高度
                    autoHeightEnabled: false, // 禁用自动高度 - 设为 true 可自适应高度
                    enableScaleImage: imgResizable, // 是否允许缩放图片

                    // 禁用自动处理功能
                    autoTransWord: false, // 禁用自动转单词
                    autoClearEmptyNode: false, // 禁用自动清空节点
                    enableAutoSave: false, // 禁用自动保存
                    // 合并用户自定义配置
                    ...config,
                };
                // 创建 UEditor 实例
                ueInstance.current = window.UE.getEditor(editorContainer.current.id, editorConfig);
                // 监听编辑器准备就绪事件
                ueInstance.current.addListener('ready', () => {
                    ueInstance.current.isReady = true; // 标记编辑器已就绪

                    // 初始内容设置
                    if (value && !isEmptyContent(value)) {
                        ueInstance.current.setContent(value);
                        isPlaceholderActive.current = false;
                    } else {
                        setPlaceholderText(); // 设置默认提示
                    }
                    updateCssVariable(); // 更新 CSS 变量
                    setupImageHandlers(); // 设置图片处理器
                    setupPlaceholderHandlers(); // 设置占位符处理器

                    // 初始修正图片尺寸
                    setTimeout(() => safeImageSizeFix(true), 300);
                });
                // 监听编辑器错误事件
                ueInstance.current.addListener('error', (error: any) => {
                    console.error('UEditor错误:', error);
                });
            }
        } catch (error) {
            console.error('UEditor初始化失败:', error);
        } finally {
            isInitializing.current = false; // 重置初始化状态
        }
    }, [
        UEDITOR_BASE_PATH,
        initLoader,
        loadScript,
        safeDestroyEditor,
        value,
        multiImageUploadUrl,
        multiImageFieldName,
        multiImageMaxSize,
        multiImageAllowFiles,
        imgResizable,
        config,
        updateCssVariable,
        setupImageHandlers,
        setupPlaceholderHandlers,
        safeImageSizeFix,
        isEmptyContent,
        setPlaceholderText
    ]);

    // 组件挂载和卸载的生命周期效果
    useEffect(() => {
        initEditor(); // 组件挂载时初始化编辑器
        return () => safeDestroyEditor(); // 组件卸载时销毁编辑器
    }, [initEditor, safeDestroyEditor]);

    // 监听 value 属性变化的效果
    useEffect(() => {
        // 如果编辑器未就绪、value 未定义或正在更新内容，则忽略
        if (!ueInstance.current?.isReady || value === undefined || isContentUpdating.current) return;

        const currentContent = ueInstance.current.getContent();
        const shouldShowPlaceholder = isEmptyContent(value);

        // 只有当内容确实发生变化时才更新
        if (value !== currentContent && !(shouldShowPlaceholder && isPlaceholderActive.current)) {
            isContentUpdating.current = true; // 标记正在更新内容

            if (shouldShowPlaceholder) {
                setPlaceholderText();
            } else {
                ueInstance.current.setContent(value);
                isPlaceholderActive.current = false;
            }
            setTimeout(() => {
                safeImageSizeFix(true); // 修正图片尺寸
                isContentUpdating.current = false; // 重置更新状态
            }, 50);
        }
    }, [value, safeImageSizeFix, isEmptyContent, setPlaceholderText]);
    // 渲染编辑器容器
    return (
        <div
            ref={editorContainer} // 容器引用
        />
    );
});

// 设置组件显示名称（用于 React DevTools）
UEditor.displayName = 'UEditor';

export default UEditor;